#include "mutex.h"
#include "iqueue.h"

void *iqueue_init()
{
    QUEUE *q = NULL;

    if((q = (QUEUE *)calloc(1, sizeof(QUEUE))))
    {
        MUTEX_INIT(q->mutex);
    }
    return q;
}

void iqueue_push(void *queue, int data)
{
    QUEUE *q = (QUEUE *)queue;
    QNODE *node = NULL;

    if(q)
    {
        MUTEX_LOCK(q->mutex);
        if((node = q->left))
        {
            q->left = node->next;
        }
        else node = (QNODE *)calloc(1, sizeof(QNODE));
        if(node)
        {
            node->data = data;
            if(q->last)
            {
                q->last->next = node;
                q->last = node;
            }
            else
            {
                q->first = q->last = node;
            }
            node->next = NULL;
            q->total++;
        }
        MUTEX_UNLOCK(q->mutex);
    }
    return ;
}

void iqueue_head(void *queue, int *data)
{
    QUEUE *q = (QUEUE *)queue;
    QNODE *node = NULL;

    if(q)
    {
        if((node = q->first))
        {
            *data = node->data;
        }
    }
    return ;
}

void iqueue_pop(void *queue, int *data)
{
    QUEUE *q = (QUEUE *)queue;
    QNODE *node = NULL;

    if(q)
    {
        MUTEX_LOCK(q->mutex);
        if((node = q->first))
        {
            *data = node->data;
            if((q->first = q->first->next) == NULL)
            {
                q->last = NULL;
            }
            node->next = q->left;
            q->left = node;
            --(q->total);
        }
        MUTEX_UNLOCK(q->mutex);
    } 
    return ;
}

void iqueue_clean(void *queue)
{
    QUEUE *q = (QUEUE *)queue;
    QNODE *node = NULL;

    if(q)
    {
        while((node = q->first))
        {
            q->first = node->next;
            free(node);
        }
        while((node = q->left))
        {
            q->left = node->next;
            free(node);
        }
        MUTEX_DESTROY(q->mutex);
        free(q);
    }
    return ;
}
